<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <p data-lake-id="u66f86fd9" id="u66f86fd9"><br></p>
  <p data-lake-id="u3c8e4340" id="u3c8e4340"><span data-lake-id="u9ad1a29a" id="u9ad1a29a">这是一个比较经典的多线程之间协调与通信的问题，首先比较容易想到的就是使用wait notify，两个线程之间互相等待，并互相通信。</span></p>
  <p data-lake-id="u14d9b485" id="u14d9b485"><br></p>
  <pre lang="java"><code>
/**
 * 使用wait notify
 * @author Hollis
 */
public class SequentialPrinter {
    private static final Object lock = new Object();
    private static int number = 1;
    private static final int MAX_NUMBER = 100;

    public static void main(String[] args) {
        Thread oddThread = new Thread(new OddPrinter());
        Thread evenThread = new Thread(new EvenPrinter());

        oddThread.start();
        evenThread.start();
    }

    static class OddPrinter implements Runnable {
        @Override
        public void run() {
            while (number &lt;= MAX_NUMBER) {
                synchronized (lock) {
                    if (number % 2 == 0) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        System.out.println(number);
                        number++;
                        lock.notify();
                    }
                }
            }
        }
    }

    static class EvenPrinter implements Runnable {
        @Override
        public void run() {
            while (number &lt;= MAX_NUMBER) {
                synchronized (lock) {
                    if (number % 2 == 1) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        System.out.println(number);
                        number++;
                        lock.notify();
                    }
                }
            }
        }
    }
}


</code></pre>
  <p data-lake-id="u07b06b90" id="u07b06b90"><span data-lake-id="u5152445c" id="u5152445c">​</span><br></p>
  <p data-lake-id="uf1a64187" id="uf1a64187"><span data-lake-id="u8cb52132" id="u8cb52132">在这个示例中，我们使用了 wait() 和 notify() 方法来实现线程之间的通信和协调。</span></p>
  <p data-lake-id="ubc9189c8" id="ubc9189c8"><span data-lake-id="uf165a8e3" id="uf165a8e3">​</span><br></p>
  <p data-lake-id="ub86aa028" id="ub86aa028"><span data-lake-id="u5691ba13" id="u5691ba13">OddPrinter 用来打印奇数，EvenPrinter 用来打印偶数，当一个线程在打印完数字后，会使用 notify() 唤醒另一个线程。这样，两个线程会交替执行，从而保证了顺序输出的要求。</span></p>
  <p data-lake-id="u5fba4c20" id="u5fba4c20"><span data-lake-id="u8a2e4ff4" id="u8a2e4ff4">​</span><br></p>
  <p data-lake-id="u079e2811" id="u079e2811"><span data-lake-id="ueb5d77d2" id="ueb5d77d2">​</span><br></p>
  <p data-lake-id="u13b7f519" id="u13b7f519"><span data-lake-id="u1bdc6211" id="u1bdc6211">除了wait-notify机制，还可以使用ReentrantLock和Condition。下面是一个使用这些类的示例代码：</span></p>
  <p data-lake-id="u69c2498c" id="u69c2498c"><span data-lake-id="u3df24611" id="u3df24611">​</span><br></p>
  <pre lang="java"><code>
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 使用ReentrantLock+Condition
 * @author Hollis
 */
public class SequentialPrinterWithLock {
    private static final Lock lock = new ReentrantLock();
    private static final Condition oddCondition = lock.newCondition();
    private static final Condition evenCondition = lock.newCondition();
    private static int number = 1;
    private static final int MAX_NUMBER = 100;

    public static void main(String[] args) {
        Thread oddThread = new Thread(new OddPrinter());
        Thread evenThread = new Thread(new EvenPrinter());

        oddThread.start();
        evenThread.start();
    }

    static class OddPrinter implements Runnable {
        @Override
        public void run() {
            while (number &lt; MAX_NUMBER) {
                lock.lock();
                try {
                    if (number % 2 == 0) {
                        oddCondition.await();
                    }

                    System.out.println(number);
                    number++;
                    evenCondition.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    static class EvenPrinter implements Runnable {
        @Override
        public void run() {
            while (number &lt; MAX_NUMBER) {
                lock.lock();
                try {
                    if (number % 2 != 0) {
                        evenCondition.await();
                    }

                    System.out.println(number);
                    number++;
                    oddCondition.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}

</code></pre>
  <p data-lake-id="u1bc8e52f" id="u1bc8e52f"><span data-lake-id="u0fcef58b" id="u0fcef58b">​</span><br></p>
  <p data-lake-id="u9382033f" id="u9382033f"><span data-lake-id="u5ec468ec" id="u5ec468ec">还可以使用Java提供的 Semaphore 等并发工具来实现线程的协调和顺序打印。下面是一个使用 Semaphore 的示例代码：</span></p>
  <p data-lake-id="u5a4e713a" id="u5a4e713a"><span data-lake-id="uee2e63b7" id="uee2e63b7">​</span><br></p>
  <pre lang="java"><code>
import java.util.concurrent.Semaphore;

/**
 * 使用信号量
 * @author hollis
 */
public class SequentialPrinterWithSemaphore {
    private static final Semaphore oddSemaphore = new Semaphore(1);
    private static final Semaphore evenSemaphore = new Semaphore(0);
    private static int number = 1;
    private static final int MAX_NUMBER = 100;

    public static void main(String[] args) {
        Thread oddThread = new Thread(new OddPrinter());
        Thread evenThread = new Thread(new EvenPrinter());

        oddThread.start();
        evenThread.start();
    }

    static class OddPrinter implements Runnable {
        @Override
        public void run() {
            while (number &lt; MAX_NUMBER) {
                try {
                    oddSemaphore.acquire();
                    if (number % 2 == 0) {
                        oddSemaphore.release();
                    } else {
                        System.out.println(number);
                        number++;
                        evenSemaphore.release();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class EvenPrinter implements Runnable {
        @Override
        public void run() {
            while (number &lt; MAX_NUMBER) {
                try {
                    evenSemaphore.acquire();
                    if (number % 2 == 1) {
                        evenSemaphore.release();
                    } else {
                        System.out.println(number);
                        number++;
                        oddSemaphore.release();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

</code></pre>
 </body>
</html>